<?php 

class webtreats_video_shortcodes {
	var $version = '6.2.17';
	var $settings = array();
	var $defaultsettings = array();
	var $swfobjects = array();
	var $usedids = array();
	var $standardcss;
	var $cssalignments;
	var $flvskins = array();
	var $wpheadrun = FALSE;
	var $adminwarned = FALSE;
	var $customfeedtext;

	// Class initialization
	function webtreats_video_shortcodes() {
		global $wpmu_version, $shortcode_tags, $wp_scripts;


		// Create default settings array
		$this->defaultsettings = apply_filters( 'vvq_defaultsettings', array(
			'youtube' => array(
				'button'          => 1,
				'width'           => 425,
				'height'          => 344,
				'color1'          => '#666666',
				'color2'          => '#EFEFEF',
				'border'          => 0,
				'rel'             => 0,
				'fs'              => 1,
				'autoplay'        => 0,
				'loop'            => 0,
				'showsearch'      => 0,
				'showinfo'        => 0,
				'hd'              => 0,
				'previewurl'      => 'http://www.youtube.com/watch?v=zlfKdbWwruY',
				'aspectratio'     => 1,
				'framed'     	  => 1,
				'align'     	  => '',
			),
			'vimeo' => array(
				'button'          => 1,
				'width'           => 400,
				'height'          => 300,
				'color'           => '#00ADEF',
				'portrait'        => 0,
				'title'           => 1,
				'byline'          => 1,
				'fullscreen'      => 1,
				'previewurl'      => 'http://www.vimeo.com/240975',
				'aspectratio'     => 1,
				'framed'     	  => 1,
				'align'     	  => '',
			),
			'alignment'           => '',
			'tinymceline'         => 1,
			'customcss'           => '',
			'customfeedtext'      => '',
		) );
		// Default customfeedtext. Change it via the settings page.
		$this->customfeedtext = '<em>' . __( 'Click here to view the embedded video.', 'vipers-video-quicktags' ) . '</em>';


		// Use the defaults as a base, merge in any user defined changes
		$this->settings = $this->defaultsettings;
		if ( $usersettings !== $this->defaultsettings ) {
			foreach ( (array) $usersettings as $key1 => $value1 ) {
				if ( is_array($value1) ) {
					foreach ( $value1 as $key2 => $value2 ) {
						$this->settings[$key1][$key2] = $value2;
					}
				} else {
					$this->settings[$key1] = $value1;
				}
			}
		}

		// Register general hooks
		add_action( 'wp_head', array(&$this, 'Head') );
		add_action( 'the_content', array(&$this, 'SWFObjectCalls'), 50 );
		add_filter( 'widget_text', 'do_shortcode', 11 ); // Videos in the text widget
		add_action( 'widget_text', array(&$this, 'SWFObjectCalls'), 50 );

		// Register shortcodes
		add_shortcode( 'youtube', array(&$this, 'shortcode_youtube') );
		add_shortcode( 'vimeo', array(&$this, 'shortcode_vimeo') );
		

		// Replace bundled SWFObject if it's older
		if ( !is_a($wp_scripts, 'WP_Scripts') )
			$wp_scripts = new WP_Scripts();
		if ( !empty($wp_scripts->registered) && !empty($wp_scripts->registered['swfobject']) && !empty($wp_scripts->registered['swfobject']->ver) && version_compare( $wp_scripts->registered['swfobject']->ver, '2.2', '<' ) ) {
			wp_deregister_script( 'swfobject' );
			wp_enqueue_script( 'swfobject', WEBTREATS_JS .'/swfobject.js', array(), '2.2' );
		} else {
			wp_enqueue_script( 'swfobject' );
		}
	}


	// Output the head stuff
	function Head() {
		$this->wpheadrun = TRUE;

		//echo "<!-- Vipers Video Quicktags v" . $this->version . " | http://www.viper007bond.com/wordpress-plugins/vipers-video-quicktags/ -->\n<style type=\"text/css\">\n";

		$aligncss = str_replace( '\n', ' ', $this->cssalignments[$this->settings['alignment']] );
		$standardcss = $this->StringShrink( $this->standardcss );
		echo strip_tags( str_replace( '/* alignment CSS placeholder */', $aligncss, $standardcss ) );

		// WPMU can't use this to avoid them messing with the theme
		if ( empty($wpmu_version) )
			echo ' ' . strip_tags( $this->StringShrink( $this->settings['customcss'] ) );

		?>
<script type="text/javascript">
/* <![CDATA[ */
	var vvqflashvars = {};
	var vvqparams = { wmode: "opaque", allowfullscreen: "true", allowscriptacess: "always" };
	var vvqattributes = {};
	var vvqexpressinstall = "<?php echo WEBTREATS_JS .'/expressinstall.swf'; ?>";
/* ]]> */
</script>
<?php
	}


	// Replaces tabs, new lines, etc. to decrease the characters
	function StringShrink( $string ) {
		if ( empty($string) ) return $string;
		return preg_replace( "/\r?\n/", ' ', str_replace( "\t", '', $string ) );
	}


	// Conditionally output debug error text
	function error( $error ) {
		global $post;

		// If the user can't edit this post, then just silently fail
		if ( empty($post->ID) || ( 'post' == $post->post_type && !current_user_can( 'edit_post', $post->ID ) ) || ( 'page' == $post->post_type && !current_user_can( 'edit_page', $post->ID ) ) )
			return '';

		// But if this user is an admin, then display some helpful text
		return '<em>[' . sprintf( __('<strong>ERROR:</strong> %s', 'vipers-video-quicktags'), $error ) . ']</em>';
	}


	// Return a link to the post for use in the feed
	function postlink() {
		global $post;

		if ( empty($post->ID) )
			return ''; // This should never happen (I hope)

		$text = ( !empty($this->settings['customfeedtext']) ) ? $this->settings['customfeedtext'] : $this->customfeedtext;

		return apply_filters( 'vvq_feedoutput', '<p><a href="' . get_permalink( $post->ID ) . '">' . $text . '</a></p>' );
	}


	// No-name attribute fixing
	function attributefix( $atts = array() ) {
		// Quoted value
		if ( 0 !== preg_match( '#=("|\')(.*?)\1#', $atts[0], $match ) )
			$atts[0] = $match[2];

		// Unquoted value
		elseif ( '=' == substr( $atts[0], 0, 1 ) )
			$atts[0] = substr( $atts[0], 1 );

		return $atts;
	}


	// Generate a placeholder ID
	function videoid( $type ) {
		global $post;

		if ( empty($post) || empty($post->ID) ) {
			$objectid = uniqid("vvq-$type-");
		} else {
			$count = 1;
			$objectid = 'vvq-' . $post->ID . '-' . $type . '-' . $count;

			while ( !empty($this->usedids[$objectid]) ) {
				$count++;
				$objectid = 'vvq-' . $post->ID . '-' . $type . '-' . $count;
			}

			$this->usedids[$objectid] = true;
		}

		return $objectid;
	}


	// Reverse the parts we care about (and probably some we don't) of wptexturize() which gets applied before shortcodes
	function wpuntexturize( $text ) {
		$find = array( '&#8211;', '&#8212;', '&#215;', '&#8230;', '&#8220;', '&#8217;s', '&#8221;', '&#038;' );
		$replace = array( '--', '---', 'x', '...', '``', '\'s', '\'\'', '&' );
		return str_replace( $find, $replace, $text );
	}


	// Handle YouTube shortcodes
	function shortcode_youtube( $atts, $content = '' ) {
		$origatts = $atts;
		$content = $this->wpuntexturize( $content );

		// Handle WordPress.com shortcode format
		if ( isset($atts[0]) ) {
			$atts = $this->attributefix( $atts );
			$content = $atts[0];
			unset($atts[0]);
		}

		if ( empty($content) )
			return $this->error( sprintf( __('No URL or video ID was passed to the %s BBCode', 'vipers-video-quicktags'), __('YouTube') ) );

		if ( is_feed() )
			return $this->postlink();

		// Set any missing $atts items to the defaults
		$atts = shortcode_atts(array(
			'width'      => $this->settings['youtube']['width'],
			'height'     => $this->settings['youtube']['height'],
			'color1'     => $this->settings['youtube']['color1'],
			'color2'     => $this->settings['youtube']['color2'],
			'border'     => $this->settings['youtube']['border'],
			'rel'        => $this->settings['youtube']['rel'],
			'fs'         => $this->settings['youtube']['fs'],
			'autoplay'   => $this->settings['youtube']['autoplay'],
			'loop'       => $this->settings['youtube']['loop'],
			'showsearch' => $this->settings['youtube']['showsearch'],
			'showinfo'   => $this->settings['youtube']['showinfo'],
			'hd'         => $this->settings['youtube']['hd'],
			'framed'     => $this->settings['youtube']['framed'],
			'align'      => $this->settings['youtube']['align'],
		), $atts);

		// Allow other plugins to modify these values (for example based on conditionals)
		$atts = apply_filters( 'vvq_shortcodeatts', $atts, 'youtube', $origatts );

		// If a URL was passed
		if ( 'http://' == substr( $content, 0, 7 ) ) {

			// Playlist URL
			if ( FALSE !== stristr( $content, 'view_play_list' ) ) {
				preg_match( '#http://(www.youtube|youtube|[A-Za-z]{2}.youtube)\.com/view_play_list\?p=([\w-]+)(.*?)#i', $content, $matches );
				if ( empty($matches) || empty($matches[2]) ) return $this->error( sprintf( __('Unable to parse URL, check for correct %s format', 'vipers-video-quicktags'), __('YouTube') ) );

				$embedpath = 'p/' . $matches[2];
				$fallbacklink = $fallbackcontent = 'http://www.youtube.com/view_play_list?p=' . $matches[2];
			}
			// Normal video URL
			else {
				preg_match( '#http://(www.youtube|youtube|[A-Za-z]{2}.youtube)\.com/(watch\?v=|w/\?v=|\?v=)([\w-]+)(.*?)#i', $content, $matches );
				if ( empty($matches) || empty($matches[3]) ) return $this->error( sprintf( __('Unable to parse URL, check for correct %s format', 'vipers-video-quicktags'), __('YouTube') ) );

				$embedpath = 'v/' . $matches[3];
				$fallbacklink = 'http://www.youtube.com/watch?v=' . $matches[3];
				$fallbackcontent = '<img src="http://img.youtube.com/vi/' . $matches[3] . '/0.jpg" alt="' . __('YouTube Preview Image', 'vipers-video-quicktags') . '" />';
			}
		}
		// If a URL wasn't passed, assume a video ID was passed instead
		else {
			$embedpath = 'v/' . $content;
			$fallbacklink = 'http://www.youtube.com/watch?v=' . $content;
			$fallbackcontent = '<img src="http://img.youtube.com/vi/' . $content . '/0.jpg" alt="' . __('YouTube Preview Image', 'vipers-video-quicktags') . '" />';
		}

		// Setup the parameters
		$color1 = $color2 = $border = $autoplay = $loop = $showsearch = $showinfo = $hd = '';

		if ( '' != $atts['color1'] && $this->defaultsettings['youtube']['color1'] != $atts['color1'] )
			$color1 = '&color1=0x' . str_replace( '#', '', $atts['color1'] );

		if ( '' != $atts['color2'] && $this->defaultsettings['youtube']['color2'] != $atts['color2'] )
			$color2 = '&color2=0x' . str_replace( '#', '', $atts['color2'] );

		if ( $atts['border'] )
			$border = '&border=1';

		if ( $atts['autoplay'] )
			$autoplay = '&autoplay=1';

		if ( $atts['loop'] )
			$loop = '&loop=1';

		if ( $atts['hd'] )
			$hd = '&hd=1';

		$rel        = ( 1 == $atts['rel'] ) ? '1' : '0';
		$fs         = ( 1 == $atts['fs'] ) ? '1' : '0';
		$showsearch = ( 1 == $atts['showsearch'] ) ? '1' : '0';
		$showinfo   = ( 1 == $atts['showinfo'] ) ? '1' : '0';
		$framed     = ( 1 == $atts['framed'] ) ? ' video_frame' : '';
		$align	    = ( $atts['align'] == 'left' ) ? ' alignleft' : '';
		$align	    = ( $atts['align'] == 'right' ) ? '  alignright' : $align;
		$align	    = ( $atts['align'] == 'center' ) ? ' aligncenter' : $align;


		$objectid = $this->videoid('youtube');

		$this->swfobjects[$objectid] = array(
			'width' => $atts['width'],
			'height' => $atts['height'],
			'url' => 'http://www.youtube.com/' . $embedpath . $color1 . $color2 . $border . '&rel=' . $rel . '&fs=' . $fs . '&showsearch=' . $showsearch . '&showinfo=' . $showinfo . $autoplay . $loop . $hd,
		);
		
		return '<span class="vvqbox vvqyoutube' .$framed.$align. '" style="width:' . $atts['width'] . 'px;height:' . $atts['height'] . 'px;"><span id="' . $objectid . '"><a href="' . $fallbacklink . '">' . $fallbackcontent . '</a></span></span>';
	}
	
	
	// Handle Vimeo shortcodes
	function shortcode_vimeo( $atts, $content = '' ) {
		$origatts = $atts;
		$content = $this->wpuntexturize( $content );

		// Handle malformed WordPress.com shortcode format
		if ( isset($atts[0]) ) {
			$atts = $this->attributefix( $atts );
			$content = $atts[0];
			unset($atts[0]);
		}

		if ( empty($content) )
			return $this->error( sprintf( __('No URL or video ID was passed to the %s BBCode', 'vipers-video-quicktags'), __('Vimeo', 'vipers-video-quicktags') ) );

		if ( is_feed() )
			return $this->postlink();

		// Set any missing $atts items to the defaults
		$atts = shortcode_atts(array(
			'width'      => $this->settings['vimeo']['width'],
			'height'     => $this->settings['vimeo']['height'],
			'color'      => $this->settings['vimeo']['color'],
			'portrait'   => $this->settings['vimeo']['portrait'],
			'title'      => $this->settings['vimeo']['title'],
			'byline'     => $this->settings['vimeo']['byline'],
			'fullscreen' => $this->settings['vimeo']['fullscreen'],
			'framed'     => $this->settings['vimeo']['framed'],
			'align'      => $this->settings['youtube']['align'],
		), $atts);

		// Allow other plugins to modify these values (for example based on conditionals)
		$atts = apply_filters( 'vvq_shortcodeatts', $atts, 'vimeo', $origatts );

		// If a URL was passed
		if ( 'http://' == substr( $content, 0, 7 ) ) {
			preg_match( '#http://(www.vimeo|vimeo)\.com(/|/clip:)(\d+)(.*?)#i', $content, $matches );
			if ( empty($matches) || empty($matches[3]) ) return $this->error( sprintf( __('Unable to parse URL, check for correct %s format', 'vipers-video-quicktags'), __('Vimeo', 'vipers-video-quicktags') ) );

			$videoid = $matches[3];
		}
		// If a URL wasn't passed, assume a video ID was passed instead
		else {
			$videoid = $content;
		}

		// Setup the parameters
		$portrait   = ( 1 == $atts['portrait'] )   ? '1' : '0';
		$title      = ( 1 == $atts['title'] )      ? '1' : '0';
		$byline     = ( 1 == $atts['byline'] )     ? '1' : '0';
		$fullscreen = ( 1 == $atts['fullscreen'] ) ? '1' : '0';
		$framed     = ( 1 == $atts['framed'] ) ? ' video_frame' : '';
		$align	    = ( $atts['align'] == 'left' ) ? ' alignleft' : '';
		$align	    = ( $atts['align'] == 'right' ) ? '  alignright' : $align;
		$align	    = ( $atts['align'] == 'center' ) ? ' aligncenter' : $align;


		$objectid = $this->videoid('vimeo');

		// Gotta pass these via flashvars rather than the URL to keep for valid XHTML (Vimeo doesn't like &amp;'s)
		$flashvars = array(
			'server'        => 'www.vimeo.com',
			'clip_id'       => $videoid,
			'show_portrait' => $portrait,
			'show_title'    => $title,
			'show_byline'   => $byline,
			'fullscreen'    => $fullscreen,
		);
		if ( '' != $atts['color'] && $this->defaultsettings['vimeo']['color'] != $atts['color'] )
			$flashvars['color'] = str_replace( '#', '', $atts['color'] );

		$this->swfobjects[$objectid] = array( 'width' => $atts['width'], 'height' => $atts['height'], 'url' => 'http://www.vimeo.com/moogaloop.swf', 'flashvars' => $flashvars );

		return '<span class="vvqbox vvqvimeo' .$framed.$align. '" style="width:' . $atts['width'] . 'px;height:' . $atts['height'] . 'px;"><span id="' . $objectid . '"><a href="http://www.vimeo.com/' . $videoid . '">http://www.vimeo.com/' . $videoid . '</a></span></span>';
	}
	


	// Output the SWFObject calls that replace all of the placeholders created by the shortcode handlers with the Flash videos (this is per post now)
	function SWFObjectCalls( $content ) {
		global $wpmu_version;

		if ( is_feed() || empty($this->swfobjects) ) return $content;

		// Abort if wp_head() is missing from the theme
		//if ( FALSE == $this->wpheadrun ) return $content;

		$out .= "\n<script type=\"text/javascript\">\n";
		$out .= "/* <![CDATA[ */\n";

		foreach ( $this->swfobjects as $objectid => $embed ) {
			$out .= '	swfobject.embedSWF("' . htmlspecialchars( $embed['url'] ) . '", "' . $objectid . '", "' . $embed['width'] . '", "' . $embed['height'] . '", "9", vvqexpressinstall, ';

			if ( empty($embed['flashvars']) || !is_array($embed['flashvars']) ) {
				$out .= 'vvqflashvars';
			} else {
				$out .= '{ ';

				$embed['flashvars'] = array_merge( array( 'wmode' => 'opaque', 'allowfullscreen' => 'true', 'allowscriptacess' => 'always' ), $embed['flashvars'] );
				$flashvars = array();

				foreach ( $embed['flashvars'] as $property => $value ) {
					if ( false === $value )
						continue;

					$flashvars[] = '"' . js_escape( $property ). '": "' . js_escape( $value ) . '"';
				}

				$out .= implode( ', ', $flashvars );
				$out .= ' }';
			}

			$out .= ", vvqparams, vvqattributes);\n";
		}

		$out .= "/* ]]> */\n"; // This gets broken by the_content(), so we can't use it
		$out .= "</script>\n";

		// Clear outputted calls
		$this->swfobjects = array();

		echo $out;
		
		return $content;
	}


	// WordPress' js_escape() won't allow <, >, or " -- instead it converts it to an HTML entity. This is a "fixed" function that's used when needed.
	function js_escape($text) {
		$safe_text = addslashes($text);
		$safe_text = preg_replace('/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes($safe_text));
		$safe_text = preg_replace("/\r?\n/", "\\n", addslashes($safe_text));
		$safe_text = str_replace('\\\n', '\n', $safe_text);
		return apply_filters('js_escape', $safe_text, $text);
	}


	// This function always return FALSE (who woulda guessed?)
	function ReturnFalse() { return FALSE; }
}

// Start this plugin once all other plugins are fully loaded
add_action( 'init', 'webtreats_video_shortcodes' ); function webtreats_video_shortcodes() { global $webtreats_video_shortcodes; $webtreats_video_shortcodes = new webtreats_video_shortcodes(); }

?>